package com.lichao.bianpai;

import javax.tools.*;
import java.io.File;
import java.io.PrintWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
import java.util.List;


public class DynamicClassBuilder {

    public static void executeCode(String code, String className, String methodName) throws Exception {
        // Step 1: 创建临时.java文件
        File sourceFile = new File(className + ".java");
        try (PrintWriter out = new PrintWriter(sourceFile)) {
            out.print(code);
        }

        // Step 2: 获取Java编译器
        JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

        // Step 3: 设置诊断监听器用于捕获编译错误
        DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();

        // Step 4: 创建标准文件管理器
        StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);

        // Step 5: 将源文件转换为编译器可识别的格式
        Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(Collections.singletonList(sourceFile));

        // Step 6: 执行编译
        boolean success = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits).call();

        if (success) {
            System.out.println("编译成功");

            // 加载编译后的类
            URLClassLoader classLoader = URLClassLoader.newInstance(new URL[]{new File("").toURI().toURL()});
            Class<?> cls = Class.forName(className, true, classLoader);
            System.out.println("加载类：" + cls.getName());

            // 使用反射创建对象实例（假设有一个无参构造函数）
            Object instance = cls.getDeclaredConstructor().newInstance();

            // 查找方法并调用它（这里假设ReverseList不接受参数）
            // 查找方法并调用它，考虑到ReverseList(List head)需要一个参数
            Method method = cls.getMethod(methodName, List.class); // 注意：这里指定了方法签名
            Object result = method.invoke(instance, Collections.emptyList()); // 提供一个空的List作为参数

            System.out.println("方法返回结果：" + result);
        } else {
            // 输出编译错误信息
            for (Diagnostic diagnostic : diagnostics.getDiagnostics()) {
                System.out.println(diagnostic.getMessage(null));
            }
        }

        // 关闭文件管理器
        fileManager.close();

        // 删除临时文件
        sourceFile.deleteOnExit();
    }

    public static void main(String[] args) {
        String code = "import java.util.*;\n\npublic class Solution {\n    public String ReverseList(List head) {\n\tSystem.out.println(\"执行成功123\");\n\treturn \"111\";\n    }\n}";
        String className = "Solution";
        String methodName = "ReverseList";

        try {
            // 注意：由于ReverseList方法需要参数，这里需要根据实际情况传递正确的参数或修改方法签名
            executeCode(code, className, methodName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}